在 JavaScript 中,變數(或常數)根據可以保存不同類型的值,值的型別(type)可以分為兩大類:原始型別 和 物件型別。這兩種型別有各自的特性,它們之間最重要的差異之一就是它們的傳值 / 傳參考特性,這直接影響到變數如何儲存和傳遞這些值。
原始型別(Primitive Types)是 JavaScript 中的基本資料型別,
這類型的值本身是原始定義的值,且它們是不可變的。
目前所有的原始型別包括:Null、Undefined、Boolean、Number、String,
以及後來新增的 Symbol 和 BigInt(後兩者較不常見,這裡就不詳述)。
以下是簡單的表格以及範例:
| 型別 | typeof 回傳值 |
描述 |
|---|---|---|
| Null | "object" | 空型別只有一個值:null。 |
| Undefined | "undefined" | 未定義型別,一個未被賦值的變數有 undefined 值。 |
| Boolean | "boolean" | 布林型別只有兩個值:true 與 false。 |
| Number | "number" | 數字型別包括數字,以及三個符號值:+Infinity、-Infinity、NaN。 |
| String | "string" | 字串型別用來代表文字資料。 |
| Symbol | "symbol" | (ES6 新增)用於創建唯一且不可變的值,通常用作物件的屬性名稱。 |
| BigInt | "bigint" | (ES11 新增)用來表示大整數的型別。 |
let a = null; // Null 型別
let b; // 未給予初始值,所以它現在是未定義型別,值為 undefined
let c = true; // 布林型別
let d = 123; // 數值型別
let e = 'Hello!'; // 字串型別
console.log(typeof a); // 輸出 "object"
console.log(typeof b); // 輸出 "undefined"
console.log(typeof c); // 輸出 "boolean"
console.log(typeof d); // 輸出 "number"
console.log(typeof e); // 輸出 "string"
這裡有幾點要注意:
typeof null 卻會回傳 "object",NaN 雖然是非數字(not-a-number)的意思,但它仍屬於數字型別,typeof NaN 會回傳 "number"。物件型別(Object Types) 是 JavaScript 中的複合型別,用於儲存多個值和屬性。
原始型別以外的型別都可歸類在物件型別,關於物件(Object)會再之後以獨立的主題詳細介紹。
主要的物件型別包括:物件(Object)、陣列(Array)、函數(Function)等。
以下是簡單的範例:
let w = new Date();
let x = { name: 'John' };
let y = [1, 2, 3];
let z = function () {
console.log('Hello World!');
};
console.log(typeof w); // 輸出 "object"
console.log(typeof x); // 輸出 "object"
console.log(typeof y); // 輸出 "object"
console.log(typeof z); // 輸出 "function",但實際上它仍屬於物件的一種
在程式語言中,「傳值」和「傳參考」是用來描述資料在變數之間如何傳遞的兩個概念。在 JavaScript 中,這兩者更是到原始型別和物件型別的主要差異。
傳值(by Value)」當一個原始型別的變數被賦值給另一個變數時,實際上是將原始值複製一份放到新的記憶體上給新變數用,這意味著原變數和新變數之間是相互獨立的,修改其中一個不會影響另一個。
let a = 5;
let b = a; // 原始型別為「傳值」
a = 10; // 修改 a 的值將不影響 b
console.log(a); // 輸出 10
console.log(b); // 輸出 5
傳參考(by Reference)」當一個物件型別的變數被賦值給另一個變數時,實際上是將原變數參考的記憶體位置給到新變數。這意味著原變數和新變數都指向相同的物件,修改其中一個物件中的屬性與方法都將會影響另一個。
let obj1 = { name: 'Alice' };
let obj2 = obj1; // 物件型別為「傳參考」
obj1.name = 'Bob'; // 修改 obj1 的屬性將會影響 obj2,因它他們實際上指向同一個物件
console.log(obj1.name); // 輸出 'Bob'
console.log(obj2.name); // 輸出 'Bob'
當想要複製一個獨立的新物件,其實是要透過「淺層複製」或「深層複製」,但這還是留到之後的物件主題再講吧。
今天介紹了 原始型別(Primitive Types) 和 物件型別(Object Types),以及它們的 傳值(by Value) 與 傳參考(by Reference) 的概念,其中物件型別的傳參考特性是要特別注意的。
那麼今天就到這邊,我們明天見~